home *** CD-ROM | disk | FTP | other *** search
/ Best Tools for JAVA / Best Tools for JAVA.iso / JAVA_ALL / IDE / SUBARTIC / SUB_ARCT / TEST / SHADE.JAV < prev    next >
Encoding:
Text File  |  1996-10-04  |  12.3 KB  |  426 lines

  1. package sub_arctic.test;
  2.  
  3. import sub_arctic.lib.*;
  4. import sub_arctic.input.*;
  5. import sub_arctic.anim.*;
  6. import sub_arctic.output.*;
  7.  
  8. import java.awt.Point;
  9.  
  10. /**
  11.  * This is the class for building a "window shade" composition object.  This
  12.  * object composes two children, one that forms the background (inside the
  13.  * window pane) and one that is on a movable shade that can be pulled up and
  14.  * down by th user.  This interaction can replace typical pop-up modal dialogs
  15.  * with an interaction that is richer in metaphor and more familiar to most 
  16.  * users.
  17.  *
  18.  * @author Ian Smith
  19.  */
  20. public class shade extends base_parent_interactor 
  21.   implements pressable, animatable {
  22.  
  23.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  24.  
  25.   /**
  26.    * String length in pixels
  27.    */
  28.   protected final int string_length=30;
  29.  
  30.   /**
  31.    * Size of the handle in pixels (both width and height)
  32.    */
  33.   protected final int handle_size=10;
  34.  
  35.   /**
  36.    * pane borders in pixels (around the outside of the window)
  37.    */
  38.   protected final int pane_borders=3;
  39.  
  40.   /**
  41.    * This is how long the animation takes, in millseconds 
  42.    */
  43.   protected final long anim_length=1500;
  44.  
  45.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  46.  
  47.   /**
  48.    * This is true if an animation is in progress
  49.    */
  50.   protected boolean anim_in_progress=false;
  51.  
  52.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  53.  
  54.   /**
  55.    * This holds how far "down" the shade is as a percentage. At 
  56.    * 100 percent down (1.0), it doesn't cover all the area, there is some
  57.    * area left for the string and chain to hang into. 
  58.    */
  59.   protected double _percent_down=0.9;
  60.  
  61.   /**
  62.    * Access to how far "down" the shade is as a percentage. At 
  63.    * 100 percent down (1.0), it doesn't cover all the area, there is some
  64.    * area left for the string and chain to hang into. 
  65.    */
  66.   public double percent_down() {return _percent_down;}
  67.  
  68.   /**
  69.    * Set how far "down" the shade is as a percentage. At 
  70.    * 100 percent down (1.0), it doesn't cover all the area, there is some
  71.    * area left for the string and chain to hang into. 
  72.    */
  73.   public void set_percent_down(double v) 
  74.     {
  75.       if (_percent_down != v)
  76.     {
  77.       _percent_down = v;
  78.       damage_self();
  79.     }
  80.     } 
  81.  
  82.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  83.  
  84.   /** Simple constructor assuming that position and size will be set with 
  85.    *  constraints */
  86.   public shade() {
  87.     super(0,0,100,100);
  88.     setup_for_fixed_children(2);
  89.   }
  90.  
  91.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  92.  
  93.   /** 
  94.    * Draw the child and the window dressing
  95.    */
  96.   public void draw_self_local(drawable d) {
  97.     color_scheme cs=style_manager.default_color_scheme();
  98.     int center_x, center_y; // what the user perceives as the center
  99.     int shade_boundary,bottom_boundary;
  100.     
  101.     /* traverse into first child and draw */
  102.     if (child(0) != null) child(0).draw_self(d);
  103.  
  104.     /* now clear the bottom area */
  105.     d.setColor(cs.base());
  106.     d.fillRect(0,h()-(string_length + handle_size), w(),
  107.            string_length + handle_size);
  108.  
  109.     /* draw the panes */
  110.     center_x=w()/2;
  111.     center_y=(h()- (string_length + handle_size)) /2;
  112.  
  113.     /* figure out where shade ends in y */
  114.     shade_boundary=(int)((percent_down() * 
  115.               ((double)(h()-(string_length + handle_size)))));
  116.  
  117.     /* draw the string and handle */
  118.     d.setColor(cs.foreground());
  119.     d.drawLine(w()/2,shade_boundary,w()/2,shade_boundary+string_length);
  120.     d.drawArc((w()/2)-(handle_size/2),shade_boundary+string_length,
  121.           handle_size, handle_size, 0, 360);
  122.  
  123.     /* now draw the shade part */
  124.     d.setColor(cs.base());
  125.     d.fillRect(0,0,w(),shade_boundary);
  126.  
  127.     /* now do second child, on the top */
  128.     if (child(1) != null) child(1).draw_self(d);
  129.  
  130.     /* finally do border over the top */
  131.     d.setColor(cs.foreground());
  132.     bottom_boundary=(h()-(string_length+handle_size))-pane_borders;
  133.     d.fillRect(0,0,w(),pane_borders); /* top */
  134.     d.fillRect(0,0,pane_borders,bottom_boundary); /* left */
  135.     d.fillRect(w()-pane_borders,0,pane_borders,bottom_boundary); /* right */
  136.     d.fillRect(0,bottom_boundary,w(),pane_borders); /* bottom */
  137.  
  138.     d.fillRect(0,shade_boundary-(pane_borders-1),w(),pane_borders-1);
  139.   }
  140.  
  141.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  142.  
  143.   /**
  144.    * Whenever we get a call to configure, be sure to enforce 
  145.    * the shade on the second child.
  146.    */
  147.   public void configure() {
  148.     int space, shift;
  149.  
  150.     super.configure();
  151.  
  152.     /* figure out how much space we have */
  153.     space=h()-(string_length+ handle_size);
  154.  
  155.     /* now what number of pixels of shift do we need */
  156.     shift=(int) (((double)space)*percent_down());
  157.  
  158.     /* we want the bottom edge of child 1 to at the bottom of the shade */
  159.     if (child(1) != null)
  160.       {
  161.     /* position the second child on the shade */
  162.     child(1).set_y(shift - child(1).h());
  163.       }
  164.   }
  165.  
  166.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  167.  
  168.   /**
  169.    * Handle the picking sequence. We need to determine where 
  170.    * the user's input is w.r.t. to us. We only make ourselves
  171.    * the picked object when they click on the handle, but we 
  172.    * don't want children getting picked if they click on any
  173.    * of the blank areas or the frame.
  174.    */
  175.   public void pick(int pt_x, int pt_y, pick_collector pick_list)  {
  176.     int shade_boundary;
  177.     Point child_point;
  178.  
  179.     /* if they are close to the edges, they are on the frame and we'll
  180.        just ignore those */
  181.     if ((pt_x < pane_borders) || (pt_x > (w()-pane_borders)) ||
  182.     (pt_y < pane_borders) || (pt_y > (h()-pane_borders))) {
  183.       /* nobody can be picked, we just return */
  184.       return;
  185.     }
  186.  
  187.     /* figure out where shade ends in y */
  188.     shade_boundary=(int)((percent_down() * 
  189.                  ((double)(h()-(string_length + handle_size)))));
  190.  
  191.     /* enforce the picking of us if they are over the handle */
  192.     if ((pt_x>=(w()/2)-(handle_size/2))&& (pt_x<=(w()/2)+(handle_size/2)) &&
  193.     (pt_y>=(shade_boundary+string_length)) &&
  194.     (pt_y<=(shade_boundary+string_length+handle_size))) {
  195.       /* put us in the pick list and bail */
  196.       pick_list.report_pick(this);
  197.       return;
  198.     }
  199.  
  200.     /* ok, now enforce the bottom region ... */
  201.     if (pt_y>= (h()-(string_length+handle_size))) {
  202.       return;
  203.     }
  204.  
  205.     /* enforce the shade region */
  206.     if (pt_y<=shade_boundary) {
  207.       /* create a point in the childs coordinate system */
  208.       child_point= child(1).into_local(new Point(pt_x,pt_y));
  209.  
  210.       /* now let him do the pick */
  211.       child(1).pick(child_point.x, child_point.y, pick_list);
  212.     } else {
  213.       /* ok, they picked an ok area which is not covered by
  214.        * the shade... do the pick within child 0 */
  215.       /* create a point in the childs coordinate system */
  216.       child_point= child(0).into_local(new Point(pt_x,pt_y));
  217.  
  218.       /* now let him do the pick */
  219.       child(0).pick(child_point.x, child_point.y, pick_list);
  220.     }
  221.   }
  222.  
  223.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  224.  
  225.   /* we don't need to do any processing here */
  226.   public boolean release(event evt, Object user_info) {
  227.     return false;
  228.   }
  229.  
  230.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  231.  
  232.   /**
  233.    * Handle a call on the pressable interface 
  234.    */
  235.   public boolean press(event evt, Object user_info) {
  236.     long now=time_interval.now();
  237.     time_interval ti;
  238.     transition trans;
  239.     shade_trajectory traj;
  240.  
  241.     if (anim_in_progress) {
  242.       return false;
  243.     } else {
  244.       anim_in_progress=true;
  245.     }
  246.  
  247.     /* are at top ? */
  248.     if (percent_down()<=0.1) {
  249.       /* at the top */
  250.       traj=new shade_trajectory(percent_down(),0.9);
  251.     } else {
  252.       /* not at top, go up */
  253.       traj=new shade_trajectory(percent_down(), 0.03);
  254.     }
  255.  
  256.     /* no animation going on now, lets do it */
  257.     ti=new time_interval(now,now+anim_length);
  258.  
  259.     /* make the transition */
  260.     trans=new transition(this,ti,traj);
  261.  
  262.     /* schedule it */
  263.     manager.animation.schedule_transition(trans);
  264.  
  265.     return true;
  266.   }
  267.  
  268.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  269.  
  270.   /** 
  271.    * start the animation
  272.    */
  273.   public void start_transition(transition trans, trajectory traj,
  274.                    double start_t, Object start_obj, event e,
  275.                    Object user_info) {
  276.     /* nothing to do here */
  277.   }
  278.  
  279.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  280.  
  281.   /**
  282.    * we just look at the end_obj (which is a Float) and
  283.    * send that to the set_shade code
  284.    */
  285.   public void transition_step(transition trans, trajectory traj,
  286.                   double start_t, Object start_obj, 
  287.                   double end_t, Object end_obj,
  288.                   event e, Object user_info) {
  289.     Float f=(Float) end_obj;
  290.     set_percent_down(f.doubleValue());
  291.   }
  292.  
  293.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  294.  
  295.   /**
  296.    * Again, we just look at the end_obj (which is a Float) and
  297.    * set the shade to be the right position
  298.    */
  299.   public void end_transition(transition trans, trajectory traj,
  300.                  double start_t, Object start_obj,
  301.                  double end_t, Object end_obj,
  302.                  event e, Object user_info) {
  303.     Float f=(Float) end_obj;
  304.     set_percent_down(f.doubleValue());
  305.     anim_in_progress=false;
  306.   }
  307.  
  308.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  309. }
  310.  
  311. /*---------------------------------------------------------------------*/
  312.  
  313.  
  314. /**
  315.  * This is a simple little trajectory to make the shade move
  316.  */
  317. class shade_trajectory implements trajectory {
  318.  
  319.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  320.  
  321.   /**
  322.    * This is the percentage of time spent going down 
  323.    * on raises of the blind. 
  324.    */
  325.   protected static final double down_percent_of_time=0.2;
  326.  
  327.   /**
  328.    * This is the extra distance down we travel before going up
  329.    */
  330.   protected static double down_shift=0.1;
  331.  
  332.   /**
  333.    * Start and stop positions.
  334.    */
  335.   protected double start;
  336.   protected double stop;
  337.  
  338.   /*
  339.    * Pacing function 
  340.    */
  341.   protected pacer pace;
  342.  
  343.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  344.  
  345.   /*
  346.    * Initialize with a start and a stop postion 
  347.    */
  348.   public shade_trajectory(double start_pos, double stop_pos) {
  349.     start=start_pos;
  350.     stop=stop_pos;
  351.     if (start>stop) {
  352.       /* going up */
  353.       pace=new slow_in_slow_out(down_percent_of_time,2*down_percent_of_time);
  354.     } else {
  355.       /* down */
  356.       pace=new linear_pacer();
  357.     }
  358.   }
  359.  
  360.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  361.  
  362.   /* convert a time interval into a number from 0.0 to 1.0... so 
  363.    * just subtract from one 
  364.    */
  365.   public Object object_for_parm(double t) {
  366.     double delta,extra,real_start, scale;
  367.  
  368.     if (start>stop) {
  369.       /* we are going up */
  370.       if (t<down_percent_of_time) {
  371.     /* extra down part */
  372.     extra=start*down_shift;
  373.     /* scale the extra part into that time% */
  374.     extra*=(t/down_percent_of_time);
  375.     return (new Float(start+extra));
  376.       } else {
  377.     /* lets compute the extra amount down we are */
  378.     extra=start*down_shift;
  379.     /* now we can get the real starting position */
  380.     real_start=start+ extra;
  381.     /* from this (large value) we can subtract the ending value */
  382.     delta=real_start-stop;
  383.     /* now delta has the distance to travel, scale to fit in teh
  384.      * last bit of the interval */
  385.     scale= (t-down_percent_of_time)/(1.0-down_percent_of_time);
  386.     /* now figure out how far along we are */
  387.     delta*=scale;
  388.     /* ok, now compute the final value */
  389.     return (new Float( (real_start-delta)));
  390.       }
  391.     } else {
  392.       /* we are going down */
  393.       delta=stop-start;
  394.       return (new Float((delta*t)+start));
  395.     }
  396.   }
  397.  
  398.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  399.  
  400.   /**
  401.    * For now, just use a linear pacing 
  402.    */
  403.   public pacer pacing_function() {
  404.     return pace;
  405.   }
  406.  
  407.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  408.  
  409. }
  410. /*=========================== COPYRIGHT NOTICE ===========================
  411.  
  412. This file is part of the subArctic user interface toolkit.
  413.  
  414. Copyright (c) 1996 Scott Hudson and Ian Smith
  415. All rights reserved.
  416.  
  417. The subArctic system is freely available for most uses under the terms
  418. and conditions described in 
  419.   http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic/doc/usage.html 
  420. and appearing in full in the lib/interactor.java source file.
  421.  
  422. The current release and additional information about this software can be 
  423. found starting at: http://www.cc.gatech.edu/gvu/ui/sub_arctic/
  424.  
  425. ========================================================================*/
  426.